package com.bwstudio.demo.consumer.message;

import com.bwstudio.demo.consumer.model.AccountChangeEvent;
import com.bwstudio.demo.consumer.service.AccountInfoService;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@RocketMQMessageListener(topic = "topic_txmsg",
        selectorExpression = "new",
        consumerGroup = "${spring.application.name}-txmsg-bank2-new")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TxmsgConsumerNew implements RocketMQListener<String> {

    private abstract class TxMsgProcessTemplate {
        public final void doProcess(String jsonStr) {
            log.info("开始消费消息:{}", jsonStr);
            try {
                AccountChangeEvent accountChangeEvent = doParseAndValidate(jsonStr);
                operateDB(accountChangeEvent);
            } catch (Exception e) {
                log.error("topic_txmsg 消费失败", e);
                throw new RuntimeException(e.getMessage(), e);
            }
        }

        protected abstract AccountChangeEvent doParseAndValidate(String jsonStr) throws RuntimeException;

        protected abstract void operateDB(AccountChangeEvent accountChangeEvent);
    }

    private final AccountInfoService accountInfoService;

    //接收消息
    @Override
    public void onMessage(String message) {
        new TxMsgProcessTemplate() {
            @Override
            protected AccountChangeEvent doParseAndValidate(String jsonStr) throws RuntimeException {
                Gson gson = new Gson();
                return gson.fromJson(jsonStr, AccountChangeEvent.class);
            }

            @Override
            protected void operateDB(AccountChangeEvent accountChangeEvent) {

                //设置账号为李四的
                accountChangeEvent.setAccountNo("2");
                //更新本地账户，增加金额
                accountInfoService.addAccountInfoBalance(accountChangeEvent);
            }

        }.doProcess(message);

    }
}
